package getools4me;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.jdo.Extent;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import utils.UnicodeUtils;
import dao.PMF;
import domain.BlogCommentFile;
import domain.BlogFile;

public class BlogManager {

	public static final int MAXLIST = 20;

	private static Pattern pattern_comment = Pattern.compile("#(\\d+?)#");
	
	public static void addComment(Long id_org, Long id_comment) {
		PersistenceManager pm = PMF.getPM();

		BlogFile file = pm.getObjectById(BlogFile.class, id_org);
		String commentIdString = file.getCommentIdString();
		if(commentIdString==null) commentIdString = "";
		commentIdString+="#"+id_comment+"#,";
		file.setCommentIdString(commentIdString);
		
		pm.makePersistent(file);
		pm.close();
	}

	public static Long saveBlog(BlogFile file) {
		PersistenceManager pm = PMF.getPM();
		Long id = pm.makePersistent(file).getId();
		pm.close();
		return id;
	}

	public static Long saveComment(BlogCommentFile file) {
		PersistenceManager pm = PMF.getPM();
		Long id = pm.makePersistent(file).getId();
		pm.close();
		return id;
	}

	public static BlogFile getBlogFileById(Long id) {
		PersistenceManager pm = PMF.getPM();
		BlogFile bf = null;

		Query q = pm.newQuery(BlogFile.class, "this.id == " + id);
		@SuppressWarnings("unchecked")
		List<BlogFile> list_result = (List<BlogFile>) q.execute();

		if (list_result.size() > 0) {
			bf = list_result.get(0);
		}

		pm.close();
		return bf;
	}

	public static BlogCommentFile getBlogCommentFileById(Long id) {
		PersistenceManager pm = PMF.getPM();
		BlogCommentFile bf = null;

		Query q = pm.newQuery(BlogCommentFile.class, "this.id == " + id);
		@SuppressWarnings("unchecked")
		List<BlogCommentFile> list_result = (List<BlogCommentFile>) q.execute();

		if (list_result.size() > 0) {
			bf = list_result.get(0);
		}

		pm.close();
		return bf;
	}

	@SuppressWarnings("unchecked")
	public static List<BlogFile> getPageList(int pageNum) {

		int start = pageNum * MAXLIST;
		int end = start + MAXLIST;

		PersistenceManager pm = PMF.getPM();

		Query query = pm.newQuery(BlogFile.class);
		query.setOrdering(BlogFile.sortByLastModifiedDateDESC());
		query.setRange(start, end);
		List<BlogFile> list = (List<BlogFile>) query.execute();
		int size = list.size();
		size++;

		pm.close();

		return list;
	}

	@SuppressWarnings("unchecked")
	public static List<BlogFile> getAllBlogFile() {

		PersistenceManager pm = PMF.getPM();

		Query query = pm.newQuery(BlogFile.class);
		query.setOrdering(BlogFile.sortByLastModifiedDateDESC());
		List<BlogFile> list = (List<BlogFile>) query.execute();
		int size = list.size();
		size++;

		pm.close();

		return list;
	}

	@SuppressWarnings("unchecked")
	public static List<BlogCommentFile> getAllBlogCommentFile() {
		PersistenceManager pm = PMF.getPM();

		Query query = pm.newQuery(BlogCommentFile.class);
		query.setOrdering(BlogCommentFile.sortByLastModifiedDateDESC());
		List<BlogCommentFile> list = (List<BlogCommentFile>) query.execute();
		int size = list.size();
		size++;

		pm.close();

		return list;
	}

	/**
	 * delete a blog will delete all the comments
	 * 
	 * @param id
	 */
	public static void deleteBlog(Long id) {
		// delete comments first
		List<Long> list_comment = getBlogCommentIDList(id);
		PersistenceManager pm_comment = PMF.getPM();
		for (Long id_comment : list_comment) {
			pm_comment.deletePersistent(pm_comment.getObjectById(
					BlogCommentFile.class, id_comment));
		}
		pm_comment.close();
		
		// delete blog file
		PersistenceManager pm_blog = PMF.getPM();
		BlogFile bf = pm_blog.getObjectById(BlogFile.class, id);
		pm_blog.deletePersistent(bf);
		pm_blog.close();
	}

	public static void deleteBlogComment(Long id_comment) {
		// delete comment file
		PersistenceManager pm_comment = PMF.getPM();
		BlogCommentFile bcf = pm_comment.getObjectById(BlogCommentFile.class,
				id_comment);
		Long id_blog = bcf.getBlog_ID();
		pm_comment.deletePersistent(bcf);
		pm_comment.close();

		// update the comment id string in blog file
		if (id_blog != null) {
			PersistenceManager pm_blog = PMF.getPM();
			BlogFile bf = pm_blog.getObjectById(BlogFile.class, id_blog);
			String commentIdString = bf.getCommentIdString();
			if(commentIdString!=null){
				commentIdString = commentIdString.replace("#"+id_comment+"#,", "");
			}
			pm_blog.close();
		}
	}

	public static String getBlogTitle(Long id) {
		return new String(getBlogFileById(id).getTitle());
	}

	@SuppressWarnings("unchecked")
	public static Long getPreviousBlogID(long id) {

		BlogFile file_current = getBlogFileById(id);
		long mdate_current = file_current.getLastModifiedDate();
		String jdoql = "select id from " + BlogFile.class.getCanonicalName()
				+ " where lastModifiedDate > mdate_current"
				+ " parameters Long mdate_current " + " order by "
				+ BlogFile.sortByLastModifiedDateASC() + " range 0,1";

		List<Long> list = null;
		Long id_pre = null;

		PersistenceManager pm = PMF.getPM();
		Query query = pm.newQuery(jdoql);
		list = (List<Long>) query.execute(mdate_current);
		if (list.size() > 0) {
			id_pre = list.get(0);
		}

		pm.close();

		return id_pre;
	}

	@SuppressWarnings("unchecked")
	public static Long getNextBlogID(long id) {

		BlogFile file_current = getBlogFileById(id);
		long mdate_current = file_current.getLastModifiedDate();
		String jdoql = "select id from " + BlogFile.class.getCanonicalName()
				+ " where lastModifiedDate < mdate_current"
				+ " parameters Long mdate_current " + " order by "
				+ BlogFile.sortByLastModifiedDateDESC() + " range 0,1";

		List<Long> list = null;
		Long id_pre = null;

		PersistenceManager pm = PMF.getPM();
		Query query = pm.newQuery(jdoql);
		list = (List<Long>) query.execute(mdate_current);
		if (list.size() > 0) {
			id_pre = list.get(0);
		}

		pm.close();

		return id_pre;
	}

	public static void reBuildBlogCommentIDString(Long id_blog) {
		List<Long> list_commentIDs = getBlogCommentIDListUsingTitle(id_blog);

		// set blog file
		PersistenceManager pm = PMF.getPM();
		BlogFile file_blog = pm.getObjectById(BlogFile.class, id_blog);
		String commentIDString = "";
		for (Long id_comment : list_commentIDs) {
			commentIDString += "#" + id_comment + "#,";
		}
		file_blog.setCommentIdString(commentIDString);
		pm.close();
		
		// set comment file 
		PersistenceManager pm_comment = PMF.getPM();
		for(Long id_commnet : list_commentIDs){
			BlogCommentFile file_comment = pm_comment.getObjectById(BlogCommentFile.class, id_commnet);
			file_comment.setBlog_ID(id_blog);
		}
		pm_comment.close();

	}

	/**
	 * if no id, return a list with 0 size
	 * @param id_blog
	 * @return
	 */
	public static List<Long> getBlogCommentIDList(Long id_blog) {
		BlogFile file_blog = getBlogFileById(id_blog);
		String commentIdString = file_blog.getCommentIdString();
		
		List<Long> list = new ArrayList<Long>(0);
		if(commentIdString!=null){
			Matcher m = pattern_comment.matcher(commentIdString);
			while(m.find()){
				list.add(Long.valueOf(m.group(1)));
			}
		}
		return list;
	}
	
	
	@SuppressWarnings("unchecked")
	private static List<Long> getBlogCommentIDListUsingTitle(Long id_blog) {
		
		System.out.println("Different comment size");
		System.out.println("commentIDString: "+getBlogCommentIDList(id_blog));
		
		PersistenceManager pm = PMF.getPM();
		BlogFile file_blog = pm.getObjectById(BlogFile.class, id_blog);
		String title = UnicodeUtils.toStringFromUnicodeString(file_blog
				.getTitle());
		pm.close();

		String title_comment = "comment to " + '\u300a' + title + '\u300b';

		title_comment = UnicodeUtils.toUnicodeString(title_comment);

		PersistenceManager pm_comment = PMF.getPM();

		String sql = "select id from "
				+ BlogCommentFile.class.getCanonicalName()
				+ " where title == title_comment parameters String title_comment order by "
				+ BlogCommentFile.sortByLastModifiedDateASC();
		Query q = pm_comment.newQuery(sql);
		List<Long> list_commentID = (List<Long>) q.execute(title_comment);
		list_commentID.size();
		pm_comment.close();

		
		System.out.println("Checking comment with title: "+UnicodeUtils.toStringFromUnicodeString(title_comment));
		System.out.println("Result: "+list_commentID);
		System.out.println("------------------------------------");
		return list_commentID;
	}

	public static void deleteAllBlogs() {
		PersistenceManager pm = PMF.getPM();
		Extent<BlogFile> extent = pm.getExtent(BlogFile.class, false);
		for (BlogFile file : extent) {
			pm.deletePersistent(file);
		}

		pm.close();
	}

	public static void deleteAllBlogComments() {
		PersistenceManager pm = PMF.getPM();
		Extent<BlogCommentFile> extent = pm.getExtent(BlogCommentFile.class,
				false);
		for (BlogCommentFile file : extent) {
			pm.deletePersistent(file);
		}
		pm.close();
	}

	public static void main(String[] args) {

		System.out.println("null".matches("\\d+"));

	}

}
